package pl.com.kyhu.dietex3000.database.management;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistryBuilder;

import pl.com.kyhu.dietex3000.database.beans.Ingredient;
import pl.com.kyhu.dietex3000.database.beans.IngredientCategory;
import pl.com.kyhu.dietex3000.database.beans.Meal;
import pl.com.kyhu.dietex3000.database.beans.MealCategory;

public class DataManagement {
	private static SessionFactory sessionFactory;
	static {
		try {
			// sessionFactory = new
			// AnnotationConfiguration().configure().buildSessionFactory();
			Configuration conf = new Configuration().configure();
			ServiceRegistryBuilder serviceRegistryBuilder = new ServiceRegistryBuilder().applySettings(conf.getProperties());
			sessionFactory = conf.buildSessionFactory(serviceRegistryBuilder.buildServiceRegistry());
		} catch (Throwable ex) {
			throw new ExceptionInInitializerError(ex);
		}
	}

	private static Session session;
	private static Transaction tx;

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public static void shutdown() {
		sessionFactory.close();
	}

	public static void save(Object ojectToSave) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		session.saveOrUpdate(ojectToSave);
		tx.commit();
		session.close();
	}

	public static List<Meal> getAllMeals() {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Meal> mealList = session.createQuery("from Meal").list();
		for (Meal meal : mealList)
			meal.initializeSet();

		tx.commit();
		session.close();

		return mealList;
	}

	public static List<Meal> getMealsWithCategory(String category) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Meal> mealList = session.createQuery("from Meal m where m.category = :cat").setParameter("cat", category).list();
		for (Meal meal : mealList)
			meal.initializeSet();

		tx.commit();
		session.close();

		return mealList;
	}

	public static List<Ingredient> getAllIngredients() {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Ingredient> ingredientList = session.createQuery("from Ingredient").list();

		tx.commit();
		session.close();

		return ingredientList;
	}

	public static List<Ingredient> getIngredientsWithCategory(IngredientCategory category) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Ingredient> ingredientList = session.createQuery("from Ingredient i where i.category = :cat").setParameter("cat", category).list();

		tx.commit();
		session.close();

		return ingredientList;
	}

	public static IngredientCategory getIncgredientCategory(String name) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<IngredientCategory> categoryList = session.createQuery("from IngredientCategory ic where ic.name = :n").setParameter("n", name).list();
		IngredientCategory ic = categoryList.get(0);
		tx.commit();
		session.close();

		return ic;
	}

	public static Meal getMeal(Integer mealID) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Meal> mealList = session.createQuery("from Meal m where m.id = :id").setParameter("id", mealID).list();
		Meal meal = mealList.get(0);
		meal.initializeSet();
		tx.commit();
		session.close();
		return meal;

	}

	public static List<IngredientCategory> getIngredientSubCategories(IngredientCategory category) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<IngredientCategory> subCategoryList = session.createQuery("from IngredientCategory ic where ic.category = :cat")
				.setParameter("cat", category).list();

		tx.commit();
		session.close();
		return subCategoryList;
	}

	public static List<Meal> getMealsWithCategory(MealCategory category) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Meal> mealList = session.createQuery("from Meal m where m.category = :cat").setParameter("cat", category).list();
		for (Meal meal : mealList)
			meal.initializeSet();
		tx.commit();
		session.close();

		return mealList;
	}

	public static MealCategory getMealCategory(String name) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<MealCategory> categoryList = session.createQuery("from MealCategory mc where mc.name = :n").setParameter("n", name).list();
		MealCategory ic = categoryList.get(0);
		tx.commit();
		session.close();

		return ic;
	}

	public static List<MealCategory> getMealSubCategories(MealCategory category) {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<MealCategory> subCategoryList = session.createQuery("from MealCategory mc where mc.category = :cat").setParameter("cat", category)
				.list();

		tx.commit();
		session.close();
		return subCategoryList;
	}
}